package org.mags.cryptography.common;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;

/**
 * pending to implement
 * @author mgaitan
 *
 */
public class RSACryptoText implements ICryptoText {
	private RSAPublicKey publicKey;
	private RSAPrivateKey privateKey;
	private RSAPrivateKey getPrivateKey() {
		return privateKey;
	}
	private RSAPublicKey getPublicKey() {
		try {
			if(publicKey ==null) {
				BigInteger modulus = new BigInteger("F56D...", 16);
				BigInteger pubExp = new BigInteger("010001", 16);
				KeyFactory keyFactory = KeyFactory.getInstance("RSA");
				RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(modulus, pubExp);
				publicKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);		
			}
			return publicKey;
		} catch(Exception e) {
			if(e instanceof RuntimeException)
				throw (RuntimeException)e;
			else
				throw new RuntimeException(e);
		}
	}
	@Override
	public String encrypt(String text) {
		try {
			Cipher c = Cipher.getInstance("RSA");
		    c.init(Cipher.ENCRYPT_MODE, getPublicKey());
		    int l = text.length();
		    byte[] part;
		    byte[] result = new byte[(int)(64*java.lang.Math.ceil(l/20.0))];
		    int i = 0;
		    while(i*20+20<l) {
		        part = c.doFinal(text.substring(i*20,i*20+19).getBytes("UTF-8"));
		        System.arraycopy(part, 0, result, i*64, part.length);
		        i = i+1;
		    }
		    part = c.doFinal(text.substring(i*20,l-1).getBytes("UTF-8"));
		    System.arraycopy(part, 0, result, i*64, part.length);
		    return new String(result);
		} catch(Exception e) {
			if(e instanceof RuntimeException)
				throw (RuntimeException)e;
			else
				throw new RuntimeException(e);
		}
	}
	@Override
	public String decrypt(String text) {
		try {
			byte[] in = text.getBytes();
		   Cipher c = Cipher.getInstance("RSA");
		    c.init(Cipher.DECRYPT_MODE, getPrivateKey());
		    String result = "";
		    byte[] part = new byte[64];
		    int l = in.length;
		    int i = 0;
		    while(i+64<=l) {
		        System.arraycopy(in, i, part, 0, part.length);
		        result = result + new String(c.doFinal(part), "UTF-8");
		        i= i+64;
		    }
		    return result;
		} catch(Exception e) {
			if(e instanceof RuntimeException)
				throw (RuntimeException)e;
			else
				throw new RuntimeException(e);
		}
	}
}
